Today we're going to have a look at how to carry out pathfinding in your game.
Now pathfinding is a really common thing a lot of games use if you want to.
If you want to basically code an NPC to move around and things like that, you need to use pathfinding.
And it's really cool.
And I think a lot of people, um, a lot of people are interested in how to do it, basically.
Um, so.
First off, if you're not familiar with the term pathfinding, I'll explain what actually is.
So normal methods of moving NPCs go in a straight line.
So 11. over here and one point over here.
It would just go in a straight line from to and from those two points.
Okay.
That's completely fine.
However, if you have like a dynamic game where you have an NPC around a house or an NPC trying to follow
the player, the NPC needs to carry out pathfinding to basically be able to find the best path to its
target in a house.
For example, the player might be in a different room, and if you don't use pathfinding, the NPC is
going to think to go straight forward.
But they're going straight into the wall because you're on the opposite side of the wall.
So we need to be able to tell the NPC there's a part here, you can't go through that part.
You need to go outside of the room and into the other room to get to the player.
And that's what this is all about, really.
So if you want to bring your NPCs to life, you have to use pathfinding unless they're going to be doing
very simple movements.
Pathfinding is basically a must.
Now it's not too difficult.
The reason why it's covered by, you guessed it, a service called Pathfinding Service.
So we're going to take a look at that today.
So let's go and add a character in I'm going to add in um.
My own character here.
I'll be.
Just here.
Okay and don't want to move myself down a bit because I'm like.
Okay.
Perfect.
And I'm going to then go ahead and add in a, um, script into me here.
Okay.
Cool.
So let's first reference pathfinding service.
Local pathfinding.
Service is equal to game.
Get service.
Pathfinding service.
We only want to reference a final position which we want this.
We want my player to be able to reach.
So let's say the final position is over here.
I want it to reach to that part here.
So this is going to be called my end part.
Or final part or anything like that there.
Um.
So we wanted to reach from there over to there.
As reference that local n part is equal to game dot workspace dot n part.
Okay, let's also reference our NPC.
So I'm going to call it NPC.
Like this here is equal to script parent.
We also need to reference as humanoid and its upper torso humanoid NPC colon weight for child.
Humanoid humanoid.
Because whenever you use whenever you're looking at the movement of characters and stuff and animations
of characters, all that kind of stuff, you are going to be reference for humanoid.
And also the upper torso.
And the reason why.
The reason why we're referencing these things I would explain a bit later on as well.
The upper torso.
Be careful here as my cartridges are 15.
If your character is R6, you will need reference just for torso.
And if you're wanting this to be a universal script which can work for different characters, you need
to check the rig type in order to determine whether you're going to be using the upper torso or just
the torso, as our 15 character have an upper torso are six characters.
Just have a standard torso.
Okay, that's all the variables and stuff I've done at the way we want to have a go at creating our
path.
Okay.
So this is basically going to be um, creating and computing the best way to get from my my character
from where it currently is to its end part.
And to do this we first create a path.
So local path is equal to path finding service colon create path as the function we use which will then
create our path between nodes.
What we need to do now is to compute the best way to um, have to do, um, what am I trying to say
here?
Um, compute the best path.
Border path?
No.
Um.
Create.
Create the compute.
The best way to get from point A to B, basically.
But we're computing what what we've just done used up here.
So path.
Colon compute async.
It's not autocompleting.
Okay, let's keep going.
Compute.
Async.
Like that fair.
I'm not getting any errors, so it must just not have not auto completed.
That's fine.
Um, so this is basically going to be computing the best way to get there.
And we want to put in point A and point B, so the start point and the finish point.
That's why we need upper torso because we can use the players the or not the players, the NPCs torso
for the start point for the start point.
So upper torso dot position and then also the end part dot position there as well.
Okay.
Um, so it's now computed the best way to get from point A to point B and how pathfinding works is it
works via waypoints.
So basically, um, it's, it has waypoints.
Um, throughout this best path, it's computed to get there.
And we don't just say fully.
Go to the second, go to the third, go to the fourth.
And by the time you finish off, it's basically at the portal.
Ready.
I'm going to make this more difficult.
Before we do, try anything more out by adding some parts in, it needs to move around so we can actually
see it working properly.
There are some parts here.
There would have to move around.
In order to get where needs to go just so we can see it actually working in working instead of just
going from point A to B.
Okay.
So um, now I've computed this path, we want to basically fetch the waypoints.
So to fetch the waypoints we can say local waypoints is equal to path colon get waypoints.
Like this here.
So this is going to fetch a table full of all of the waypoints.
It is placed to get from A to B.
So, um, let's then create the same cycle through all those waypoints.
So for I comma v in pairs waypoints.
Um.
Do.
Cool.
Um, now this next bit is completely optional.
However, I would like to put a part at each waypoint to actually show you the path that it generated.
This is, um, completely optional because it works the exact same without these parts.
They're absolutely just visual.
So I'm going to speed through this a bit because, um, you don't necessarily need to be following along
if you like the same effect of me.
You can copy this along, but, um.
Is absolutely not required.
The position is equal to.
Free dot new 020 part dot size is equal to vector free dot new 0.20.20.2.
Part dot color is equal to color three dot new.
We don't need.
That's a new one.
111 part material is equal to enum dot material dot neon.
Typing so fast I forgot to write an equal sign.
Now um, part dot shape is equal to enum.
Part Typekit ball.
Um part dot anchored.
We need anchored is equal to true.
Forgot anything there?
Uh, it needs to be anchored by anchor light as well.
Candle light is equal to false.
Cool.
I believe that's everything.
Let's just quickly try this out.
It won't move anywhere, but it should place all the waypoints down if I've done this correctly.
There we go.
So it's generated the best path to get to get there.
And it's found out that this path here is the best one to go to.
It's going to go this way, follow the waypoints, and then go this way to get to the object.
That's the best way.
But it's it's calculated to get there and a normal without using pathfinding.
It would just go straight like that and it wouldn't be able to reach it.
Um, let's increase this a bit.
I want it to go like in out like that.
So let's increase the size of this.
Which way would it go now?
There we go.
Oh.
Um.
It.
Okay.
That's.
Okay.
That's interesting.
Um, why is it decided to go through this part?
Can't do that.
Um, I'm not too sure why it's decided to go through that part.
I mean, it's, um, it's being able to, like, go past this one.
Fine.
But, um, why might it be going through, um.
I'm not too sure.
Let's try.
Um.
I here.
Let's pull it down.
One more and up another one and just try again.
Okay.
It's now decided that's the best route again, and it's convinced that's the best route.
I don't want it to go that way.
Um.
I wanted to go in between.
Still wanting to go that way.
It still brings us the best way to go.
Um, so you can see it's very advanced.
It will pick the best route to go to your these locations.
And now you see its best route is going there.
I just want to make it do a couple turns to make it a bit cooler.
And.
There we go.
That's kind of what I wanted.
So it's going between these parts and through, um, just like that.
Cool.
Okay.
So let's go through here.
And what we want to do is for each waypoint we want it to move to that waypoint.
So we're going to say humanoid dot move to.
Um.
Sorry.
Colon.
Move to.
Okay.
Um, the dot position.
We are moving, um, our object to this position here, and we use humanoid colon move to because this
will basically make the player walk or the NPC walk to this location.
We're not just it's not going to jump and it's there.
It's going to walk to there.
And that's how you can use that there okay.
We're also going to write down humanoid dot move to finished um colon weight like this here.
And this will basically wait here until the move to is finished.
So I don't think I've really looked at this, but with events we've always done colon connect like this
here.
But you can also do colon weight.
And this here will basically wait until the event has been fired.
This basically means that it has to move to the first waypoint before it's going to make it move to
the second one.
Cool.
And so let's go try this out and see what happens.
So it's is going to start moving.
Um it's not going to start moving.
Um okay.
Mm.
Well, he's not going to start moving.
Um, I've what I've done wrong here.
Um.
Mm.
Okay.
Um.
What might be wrong here.
In case there's not moving to the first one, let me make sure I've written it correctly.
So humanoid colon move to v dot position.
Humanoid dot move to finished colon weight.
That should be fine.
Um, the only thing I could think of is if I add the extra weight.
And I'm going to explain this just yet.
This is something that I want.
I wanted to show you it working first and then to explain this a bit, but I've got a feeling that I'm
not writing this bit is messing it up a little bit.
So I'm going to explain this in a little bit.
I'm just going to see if writing it will help it basically.
So this is the entire script here.
Should work.
Doesn't work.
Um, okay.
So.
It's not working.
Let me make sure I've got everything written down correctly.
Pathfinding service.
Um.
I've missed something.
Maybe.
Pathfinding service.
And.
Well, that stuff we're computing.
Get the waypoints of these waypoints.
Go through here.
And.
Move to move to.
Finished.
Move to the end part.
The only other thing I can think of is perhaps it needs to be done locally.
Is an idea I'm thinking of.
Have I done this on the wrong, um, wrong area?
So if I copy this over into a local script, I'm just curious to see if this is going to then work.
That disabled this script.
That's not going to run.
Is it then going to work if I do it locally?
It's not.
No, I didn't think it was a local script that's doing this.
Um.
This is a strange one.
Um, none of these objects are anchored, are they?
Um, anchors?
Are.
Some of them were.
Is it because they were?
Is it because it was angered?
It wasn't okay, right?
Well, I'm not sure if it's working for you.
Um, if it's an issue with my with my character here, it might be.
It might be working for you, but, um, I'm just gonna have to have a look and see what I've done wrong
here.
That's great.
Um, let's try it.
Let's call it something different.
Let's call this NPC in case it's not liking that.
It's got the same name as me.
Um, no, it's not even displaying the, um.
Things anymore.
So it's got to be got to be on the server.
I didn't think it was going to be on the client.
It was just a guess, really.
Um.
There we go.
It's working now.
Um, so I think it didn't like the name.
Perhaps, um, because it got the same name as me.
Or maybe it was because I think it was because a parts of it were anchored.
I think is the issue because I did it, I was anchored, but it didn't change because it was on a local
script where it should be on a server script.
Okay, well, let's get rid of these parts here then, and it should then hopefully still work.
Um.
They were just ideas that I thought might be the issue.
Cool.
So it's now working as it is quite nicely.
It's going to move over and there will be an issue with this.
Hopefully you'll be able to see, um, okay.
Um, not really, but the issue I was trying to get there is that it doesn't quite reach the ends.
And I guess it's very, very close.
You could mistaken it, but I guess it's not exactly in the center just yet.
So how do we actually get it to end?
Well, the issue we have here is that we're getting it to each waypoint, but the waypoints are just
the, um.
A point in between the start and our finish.
We haven't actually gotten to our finish yet.
We've just gotten to the last waypoint.
So to get from the last waypoint to the finish, we need to add one extra little bit line of code,
basically saying humanoid.
Colon moved to an parts position outside of the for loop because once the for loop is finished and it's
gone through each waypoint, it's now going to go to this one here.
Cool.
Um, so it will now hopefully we can see a bit of a difference when we do go ahead and play it.
It will move over.
Go back into the bar over here and it's not really much difference.
I don't think it is a bit more on it, but maybe for a slightly different setup it might be a bit more
obvious.
But yeah, so that's that bit done.
And the second is a bit of an addition you can make to pathfinding service.
So let's say all these objects are quite low down to the ground.
Now there's a specific limit where if it's not low enough if it's yeah.
If it's too low the character will just be able to walk over it.
So I want it to be low enough.
Um, there's not going to be so not not too low.
It's going to jump over it.
Um, okay.
That's not good.
Why is it decided to go there?
This won't be an issue once I show you the next bit of code, but it's decided to go there.
So why might that be the case?
Um.
Think it's slightly higher.
It decides to go there for some reason.
Okay.
Let's let me keep going.
Okay, so most likely because these objects are quite low down.
Um, it's not seeing them when it calculates.
I mean, it really should.
Um, but, um, that's interesting as to how it's not, um, doing that.
Um, but it's a bit annoying.
It's not going to work properly, but the idea I wanted to get there is that it should have moved out
of the way for these objects.
Um, I think perhaps it's.
I'm making it walk such a long way off course, but it desperately tries to get back onto onto its course.
So maybe if I make it a little bit easier for it, um, like that, it might decide not to walk.
Okay.
Now it still doesn't work.
Um, maybe because the waypoint is so close.
I think maybe his waypoints are so close and this is quite a thin wall, so maybe we increase the size
of the walls.
I do just want to show you this working.
Um.
Because a very thin wall, um, it calculates it to be.
At the waypoint.
There we go.
This is how it should be working.
Okay.
So even though it could absolutely just jump over these parts, it doesn't.
Um, which we can change so we can change it so that if it's able to jump over these parts.
Um, to jump over it.
Now each waypoint actually tells us if it needs to jump or not.
It's up to us to then code the jumping.
Now this is really easy to code.
We need to check to see if the waypoint action is jumping.
So if v dot action.
So our waypoint action is equal to enum dot path waypoint action dot jump.
This basically means that it has to jump in order to reach the next waypoint.
If it is the case, then make the character jump.
And to do that, all you need to say is humanoid colon.
Change state and change state to enum dot humanoid state.
Type dot jumping.
So basically just make the humanoid jump.
And if we try this out one more time with that extra jumping, it will be able to make some shortcuts.
Um, by jumping some nice jumping there you can see, um, we'll have to make these a bit smaller then.
I think maybe it's a bit too high for it to jump.
Okay, let's try this again.
Hopefully be able to see some jumping this time.
Okay, so I think we need to then make change the size of these because basically it's.
The jumping ropes take longer, so it calculates that just going round it a tiny bit would be easier
than jumping over it.
But now that there's an object in the way, it should jump over it.
Perfect.
You can see it jumping over it like that there.
So I guess just because there's an object that it can jump over, it's not necessarily going to if that's
slower to do, um, it's going to do it the other way.
But you see it gets to this way point, it gets to this way point and it realizes, well, to go any
further, I need to go and jump.
So then it jumps over and carries on just like that.
So, um, pathfinding is really cool.
Okay.
Um, hasn't been the best to show you because it's been quite glitchy and weird, but do remember that
in a proper game, if this is if this is if this is like in in what I'm trying to say, if this is if
this is in an enclosed map, um, like a house, for example.
Um, it's not going to have nearly as many issues.
Um, so it is a bit better in practice, but the pathfinding system is pretty cool and you can make
it do all kinds of things.
Um, I've had some cool experiments of this, and I've added added like a massive maze from a toolbox,
and it's been able to go through the maze completely fine as well.
So pathfinding is a really cool addition.
And, um, it is better than what I've shown you at today.
Really.
Um, but yeah, and remember, this code here is, um, not necessarily.
It's all it's just a bit of an addition so you can see more visually what's going on.
Okay.
So hopefully you enjoyed looking at pathfinding and um, have a play around with some of applications
of that, um, to put into your own games.